from flask import Flask, request, jsonify
from flask_cors import CORS
import hmac
import hashlib
import base64
import time
import uuid
import requests
import json
import logging
from typing import Dict, Optional, Tuple

# 配置常量
APP_KEY = "hengnaoZ73S0JFmwFucCyglcBgk"
APP_SECRET = "3imquvvjytpc7ln48frxdz4mk8v4m2zd"
AGENT_ID = "f708d9e0-f35e-453a-b84c-9f896ed2fe24"
BASE_URL = "https://www.das-ai.com"
MAX_RETRIES = 3
TIMEOUT = 1000

# 配置日志
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s [%(levelname)s] %(message)s',
    handlers=[logging.StreamHandler()]
)
logger = logging.getLogger(__name__)

app = Flask(__name__)
CORS(app)


def generate_sign(key: str, secret: str) -> str:
    """生成 HMAC-SHA256 签名"""
    timestamp = int(time.time() * 1000)
    data = f"{timestamp}\n{secret}\n{key}".encode('utf-8')
    signature = hmac.new(secret.encode('utf-8'), data, hashlib.sha256).digest()
    sign = f"{timestamp}{base64.b64encode(signature).decode('utf-8').strip()}"
    logger.debug(f"生成签名: timestamp={timestamp}, sign={sign}")
    return sign


def call_das_ai_api(payload: Dict, session_id: str) -> Tuple[Optional[Dict], Optional[str]]:
    """调用 DAS AI API"""
    headers = {
        "appKey": APP_KEY,
        "sign": generate_sign(APP_KEY, APP_SECRET),
        "Content-Type": "application/json",
        "Accept": "application/json",
        "X-Session-Id": session_id
    }
    url = f"{BASE_URL}/open/api/v2/agent/execute"

    for attempt in range(MAX_RETRIES):
        try:
            logger.debug(
                f"发送请求到 {url}, 尝试 {attempt + 1}/{MAX_RETRIES}, payload={json.dumps(payload, ensure_ascii=False)}")
            response = requests.post(url, headers=headers, json=payload, timeout=TIMEOUT)
            response.raise_for_status()
            result = response.json()
            logger.debug(f"收到响应: {json.dumps(result, ensure_ascii=False, indent=2)}")
            return result, None
        except requests.exceptions.RequestException as req_err:
            error_msg = f"网络请求错误 (尝试 {attempt + 1}/{MAX_RETRIES}): {str(req_err)}"
            logger.warning(error_msg)
            if attempt == MAX_RETRIES - 1:
                return None, error_msg
        except json.JSONDecodeError as json_err:
            error_msg = f"响应解析错误: {str(json_err)}, 原始响应: {response.text}"
            logger.error(error_msg)
            return None, error_msg


def parse_assistant_response(result: Dict) -> Tuple[str, bool]:
    """解析助手的回复并判断是否成功"""
    if result.get('code', 1) != 0:
        error_msg = result.get('msg', '未知错误')
        logger.warning(f"API 返回错误: {error_msg}")
        return error_msg, False

    data = result.get('data', {})
    if 'session' in data and 'messages' in data['session']:
        messages = data['session']['messages']
        assistant_response = next(
            (msg['content'] for msg in reversed(messages) if msg.get('role') == 'assistant'),
            '无响应'
        )
        logger.debug(f"从 session.messages 解析回复: {assistant_response}")
    elif 'content' in data:
        assistant_response = data['content']
        logger.debug(f"从 data.content 解析回复: {assistant_response}")
    else:
        assistant_response = data.get('answer', '无响应')
        logger.debug(f"从 data.answer 或默认值解析回复: {assistant_response}")

    return assistant_response, True


@app.route('/chat', methods=['POST'])
def chat():
    """处理聊天请求"""
    try:
        data = request.get_json()
        if not data:
            logger.warning("收到空请求体")
            return jsonify({'code': 1, 'msg': '无效的 JSON 数据', 'sessionId': ''}), 400

        user_input = data.get('input', '')
        session_id = data.get('sessionId') or str(uuid.uuid4())  # 确保 sessionId 始终是 UUID
        logger.info(f"收到请求: input={user_input}, sessionId={session_id}")

        payload = {
            "id": AGENT_ID,
            "sid": session_id,
            "input": user_input,
            "stream": False
        }

        result, error = call_das_ai_api(payload, session_id)
        if error:
            return jsonify({'code': 1, 'msg': error, 'sessionId': session_id}), 500

        assistant_response, success = parse_assistant_response(result)
        if not success:
            return jsonify({'code': 1, 'msg': assistant_response, 'sessionId': session_id}), 400

        logger.info(f"返回成功响应: {assistant_response}")
        return jsonify({
            'code': 0,
            'response': assistant_response,
            'sessionId': session_id
        })

    except Exception as e:
        logger.error(f"处理请求时发生错误: {str(e)}")
        return jsonify({'code': 1, 'msg': f'服务器错误: {str(e)}', 'sessionId': ''}), 500


if __name__ == "__main__":
    logger.info("启动 Flask 服务")
    app.run(host='0.0.0.0', port=5000, debug=True)